#ifndef TestsHPP
#define TestsHPP
//---------------------------------------------------------------------------
#include "./mqLib.hpp"
//---------------------------------------------------------------------------
typedef bool (*TestFunction)();
std::vector< std::pair<String, TestFunction> > g_Tests;
//---------------------------------------------------------------------------

static const int ArrLength = 10;

struct TPerson
{
  String Name;
  String Phone;
  size_t Age;
};

int iSample[] = {1, -2, 3, 0, 12, 52, 7, 8, 3, 1};

TPerson pSample[] =
{
  { "Mike",     "32423", 10 },
  { "Sam",      "43948", 29 },
  { "David",    "43841", 23 },
  { "Mark",     "57810",  6 },
  { "Philip",   "91023", 54 },
  { "Dan",      "72108", 12 },
  { "Ithan",    "34821", 56 },
  { "Helen",    "78209", 19 },
  { "Jhon",     "65712", 34 },
  { "Tomas",    "06837", 41 },
};

//---------------------------------------------------------------------------

// mqUpdate
static bool TestUpdate()
{
  {
    typedef int TestType;

    std::vector<TestType> Vector(iSample, iSample + ArrLength);
    std::vector<TestType> OrigVector(iSample, iSample + ArrLength);

    mqUpdate(std::vector<TestType>, Vector, i *= 2;);

    if (OrigVector.size() != Vector.size())
      return false;

    for (size_t i = 0, cnt = Vector.size(); i < cnt; ++i)
      if (OrigVector[i] * 2 != Vector[i])
        return false;
  }

  {
    typedef TPerson TestType;

    std::vector<TestType> Vector(pSample, pSample + ArrLength);
    std::vector<TestType> OrigVector(pSample, pSample + ArrLength);

    mqUpdate(std::vector<TestType>, Vector,
      i.Age += 2;
      i.Name = "mr. " + i.Name;
      i.Phone = "(099) " + i.Phone;
    );

    if (OrigVector.size() != Vector.size())
      return false;

    for (size_t i = 0, cnt = Vector.size(); i < cnt; ++i)
    {
      const bool Fail = Vector[i].Age != OrigVector[i].Age + 2
        || Vector[i].Name  != String("mr. "  ) + OrigVector[i].Name
        || Vector[i].Phone != String("(099) ") + OrigVector[i].Phone;
      if (Fail)
        return false;
    }
  }

  {
    typedef TPerson TestType;

    typedef std::map<int, TestType> TMap;

    TMap Map;
    for (int i = 0; i < ArrLength; ++i)
      Map.insert(std::make_pair(i, pSample[i]));

    TMap OrigMap;
    for (int i = 0; i < ArrLength; ++i)
      OrigMap.insert(std::make_pair(i, pSample[i]));

    mqUpdate(TMap, Map,
      i.second.Age += i.first;
      i.second.Name = "mr. " + i.second.Name;
      i.second.Phone = "(099) " + i.second.Phone;
    );

    if (Map.size() != OrigMap.size())
      return false;

    std::vector<TMap::mapped_type> v1, v2;
    for (TMap::iterator i = Map.begin(); i != Map.end(); ++i)
      v1.push_back(i->second);

    for (TMap::iterator i = OrigMap.begin(); i != OrigMap.end(); ++i)
      v2.push_back(i->second);

    for (int i = 0; i < ArrLength; ++i)
    {
      const bool Fail = v1[i].Age != v2[i].Age + i
        || v1[i].Name != String("mr. "  ) + v2[i].Name
        || v1[i].Phone != String("(099) ") + v2[i].Phone;

      if (Fail)
        return false;
    }
  }

  return true;
}

// mqWhere

// mqRange

// mqType

// mqUnion

// mqDistinct

// mqEach

// mqReverse

// mqSort

// mqCast

// mqNew

// mqToVector

// mqToArray

// mqMax

// mqMin

// mqFirst

// mqLast

// mqSum

// mqAvg

// mqCount

// mqAny

// mqAll

// mqHas

//---------------------------------------------------------------------------
static void InitTests()
{
#define ADD(Name) g_Tests.push_back(std::make_pair(String(#Name), Name))
  ADD(TestUpdate);
#undef ADD  
}
//---------------------------------------------------------------------------
#endif
